package hsintiao.com.xintiaoAPP.service.impl;

import hsintiao.com.xintiaoAPP.entity.BodyInformation;
import hsintiao.com.xintiaoAPP.entity.User;
import hsintiao.com.xintiaoAPP.entity.vo.UserYVO;
import hsintiao.com.xintiaoAPP.mapper.BodyInformationMapper;
import hsintiao.com.xintiaoAPP.mapper.UserMapper;
import hsintiao.com.xintiaoAPP.service.LoginService;
import hsintiao.com.xintiaoAPP.util.*;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletResponse;
import java.security.PrivateKey;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;
import java.util.UUID;

@Service
@Transactional
public class LoginServiceImpl implements LoginService {
    //用于和登录的token做区别标识
    private static final  String REGISTER_CODE_PREFIX = "regiser_code:";
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private BodyInformationMapper bodyInformationMapper;

    @Override
    public AjaxResult login(Map<String, Object> params, HttpServletResponse response) {
        //1 接收参数
        String phone = (String) params.get("phone"); //通过手机号注册
        String smsCode = (String) params.get("smsCode");//短信验证码
        //判断手机号和验证码是否有空的
        if (StringUtils.isBlank(phone)||StringUtils.isBlank(smsCode)){
            return AjaxResult.me().setSuccess(false).setMessage("请输入相关参数！")
                    .setCode(ResponseCode.FAILURE.getCode());//返回code:201 和消息提示
        }
        AjaxResult ajaxResult = null;
        User byUsername = null;
        //根据手机号查找是否有对应的用户
        byUsername = userMapper.findByUsername(phone);
        if(byUsername == null){ //用户不存在
            byUsername = new User();
            byUsername.setPhone(phone);
            //内部注册
            ajaxResult = this.doRegistered(byUsername, smsCode);
            //设置是第一次注册，注册完毕后应该根据该值判断是否跳转到身体信息保存页面，默认为false，，为true时表示第一次注册，需要跳转到身体信息保存页面
            byUsername.setIsRegist(true);
            if(ajaxResult.getCode()!= 200){
                return ajaxResult;
            }
        }
        //当ajaxResult不为空时表示经过了注册这一步
        if(ajaxResult != null){
            User user = (User) ajaxResult.getResultObj();
            System.out.println("注册user="+user);
            //将注册后的用户信息获取出来并设置给byUsername用于登录
            if(user !=null){
                byUsername=user;
                System.out.println("byusername="+byUsername);
            }
        }

        //根据key获取短信验证码
        String getSmsCode = RedisUtils.INSTANCE.get(REGISTER_CODE_PREFIX+phone);
        if(getSmsCode == null || getSmsCode.equals("")){
            System.out.println("验证码错误或手机号错误");
            return AjaxResult.me().setCode(ResponseCode.FAILURE.getCode())
                    .setSuccess(false).setMessage("验证码错误或手机号错误");
        }
        //格式= 验证码:时间戳 获取第一个元素的验证码
        String code =  getSmsCode.split(":")[0];
        //String getSmsCode = "123456";
        if(code != null && !code.equals(smsCode)){
            System.out.println("验证码错误");
            return AjaxResult.me().setCode(ResponseCode.FAILURE.getCode())
                    .setMessage("验证码错误").setSuccess(false);
        }

        //token构造 redis token:jwt
        //获取私钥
        PrivateKey privateKeyPath = RsaUtils.getPrivateKey(LoginServiceImpl.class.getClassLoader()
                .getResource("hrm_auth_rsa").getFile());
        //PrivateKey privateKeyPath = RsaUtils.getPrivateKey("/yft/myProject/xtyl/authKey/hrm_auth_rsa");
        //产生jwttoken
        String jwtToken = JwtUtils.generateTokenExpireInMinutes(byUsername, privateKeyPath, 5);
        String token = UUID.randomUUID().toString();
        //保存到redis
        //String token = TokenUtils.token(username, password);
        Map<String,Object> paramsTmp = new HashMap<>();
        paramsTmp.put("key",token);
        paramsTmp.put("value",jwtToken);
        paramsTmp.put("expire",60*60*24*7);
        RedisClient.add(paramsTmp);
        //3.4 返回结果
        Map<String,Object> result = new HashMap<>();
        result.put("user",byUsername);
        result.put("token",token);

        ajaxResult= AjaxResult.me().setResultObj(result);
        return ajaxResult;
    }

    /*
    * 注册(内部注册)
    * */
    public AjaxResult doRegistered(User user,String smsCode){
        try {
            //先验证redis中对应的验证码

            //然后注册到数据库中
            userMapper.insertByRegist(user);
            return AjaxResult.me().setMessage("注册成功").setResultObj(user);
        }catch (Exception e){
            e.printStackTrace();
            return AjaxResult.me().setSuccess(false).setCode(ResponseCode.FAILURE.getCode())
                    .setMessage("注册失败");
        }
    }

    /*
    * 发送验证码
    * */
    @Override
    public AjaxResult sendSMG(String phone) {
        if(StringUtils.isEmpty(phone) || StringUtils.isBlank(phone) ||phone ==null){
            return AjaxResult.me().setCode(ResponseCode.FAILURE.getCode())
                    .setSuccess(false).setMessage("手机号为空或错误手机号");
        }
        //根据key查询短信验证码
        String registerCode = RedisUtils.INSTANCE.get(REGISTER_CODE_PREFIX + phone);
        String code = null;
        if (StringUtils.isNotBlank(registerCode)){
            //获取短信验证码的时间
            String time =  registerCode.split(":")[1];
            //60s间隔不允许重新发送短信
            /*if (System.currentTimeMillis()-Long.valueOf(time)<60*1000) {
                return AjaxResult.me().setSuccess(false).setMessage("请稍后再重新发送!")
                        .setCode(ResponseCode.FAILURE.getCode());
            }*/
            //
            code =  registerCode.split(":")[0];
        }
        //获取随机6位数验证码
        String source = "0123456789";
        Random r = new Random();
        StringBuilder rs = new StringBuilder();
        for (int j = 0; j < 6; j++) {
            rs.append(source.charAt(r.nextInt(10)));
        }
        code = rs.toString();
//      将验证码添加到redis中设置3分钟过期时间
        Map<String,Object> paramTmp = new HashMap<>();
        paramTmp.put("key",REGISTER_CODE_PREFIX+phone);
        paramTmp.put("value",code+":"+System.currentTimeMillis());
        paramTmp.put("expire",3*60);
        RedisClient.add(paramTmp);
        //调用发送短信服务
        //Map<String, String> result = SendMsg.sendSms(phone, code);
        //获取状态信息
        /*String status = result.get("Code");//注意，验证码内容的key为code,小写，而状态信息的key为Code，首字母大写
        // String status = "isv.DAY_LIMIT_CONTROL";
        System.out.println("状态status="+status);
        if(status.equals("isv.DAY_LIMIT_CONTROL")){
            return AjaxResult.me().setCode(ResponseCode.FAILURE.getCode())
                    .setSuccess(false).setMessage("当前手机号每天只能发送10条验证码信息，请隔日再尝试")
                    .setResultObj(code);
        }
        if(status.equals("isv.MOBILE_NUMBER_ILLEGAL")){
            return AjaxResult.me().setCode(ResponseCode.FAILURE.getCode())
                    .setSuccess(false).setMessage("当前手机号不是一个手机号格式");
        }
        if(status.equals("isv.BUSINESS_LIMIT_CONTROL")){
            return AjaxResult.me().setCode(ResponseCode.FAILURE.getCode())
                    .setSuccess(false).setMessage("当前手机号短时间内尝试次数过多，请1小时后重试");
        }*/
        //将短信的内容返回给前台做验证处理
        return AjaxResult.me().setResultObj(code);
    }


    //养老院注册时同时注册到本地数据库
    @Override
    @Transactional
    public AjaxResult registerForYLY(UserYVO user) {
        try {
            //创建一个新的user对象，设置相关参数
            User user1 = new User();
            user1.setPhone(user.getPhone());
            user1.setGender(user.getGender());
            user1.setAvatar(user.getAvatar());
            user1.setBirthday(user.getBirthday());
            user1.setName(user.getName());

            BodyInformation body = new BodyInformation();
            body.setWeight(user.getWeight());
            body.setHeight(user.getHeight());
            body.setHeartMedicalHistory(user.getHeartMedicalHistory());
            body.setHypertensionMedicalHistory(user.getHypertensionMedicalHistory());
            body.setDiabetesMedicalHistory(user.getDiabetesMedicalHistory());
            body.setOtherMedicalHistory(user.getOtherMedicalHistory());
            //根据手机号查询是否存在对应用户决定是更新还是保存新的用户信息
            User byUsername = userMapper.findByUsername(user.getPhone());
            if(byUsername != null){
                user1.setId(byUsername.getId());
                userMapper.updateUser(user1);
                body.setUserID(byUsername.getId());
                bodyInformationMapper.update(body);
                return AjaxResult.me().setResultObj(byUsername.getId());
            }else {
                userMapper.insertByRegistForYLY(user1);
                Long id = user1.getId();
                System.out.println("保存新的user后id="+id);
                //保存对应用户的身体信息
                body.setUserID(id);
                bodyInformationMapper.insert(body);
                return AjaxResult.me().setResultObj(id);
            }
        }catch (Exception e){
            throw e;
        }
    }
}
